package com.jordi.tetris.view;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import android.content.Context;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;

import com.jordi.tetris.model.TetrisGame;

public class TetrisView extends ViewGroup implements PropertyChangeListener {

	private static final long refreshTime = 50;

	private static final float moveThreshold = 10;

	private TetrisBoardView boardView;

	private TetrisGame game;

	private RefreshHandler mRedrawHandler = new RefreshHandler();

	private long lastTime = 0;

	private float lastX;

	private float lastY;

	class RefreshHandler extends Handler {

		@Override
		public void handleMessage(Message msg) {
			TetrisView.this.update();
		}

		public void sleep(long delayMillis) {
			this.removeMessages(0);
			sendMessageDelayed(obtainMessage(0), delayMillis);
		}
	}

	public TetrisView(Context context) {
		this(context, null, 0);
	}

	public TetrisView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public TetrisView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		game = new TetrisGame();
		game.addObserver(this);

		boardView = new TetrisBoardView(context);
		boardView.setBoard(game.getGameBoard());
		boardView.layout(40, 10, 40, 10);

		addView(boardView);
		setFocusable(false);
		boardView.setFocusable(true);
		boardView.setVisibility(VISIBLE);
		update();
	}

	public void update() {
		long curTime = System.currentTimeMillis();
		if (curTime - lastTime > refreshTime) {
			if (!game.isGameOver()) {
				game.update();
			}
			mRedrawHandler.sleep(refreshTime);
		}
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
	}

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		invalidate();
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int eventaction = event.getAction();
		
		switch (eventaction) {
		case MotionEvent.ACTION_DOWN:
			// finger touches the screen
			Log.d("DEBUG", "Action down");
			break;

		case MotionEvent.ACTION_MOVE:
			// finger moves on the screen
			Log.d("DEBUG", "Action move");
			deriveMove(event);
			break;

		case MotionEvent.ACTION_UP:
			// finger leaves the screen
			Log.d("DEBUG", "Action up");
			break;
		}

		lastX = event.getX();
		lastY = event.getY();

		// tell the system that we handled the event and no further processing
		// is required
		return true;
	}

	private void deriveMove(MotionEvent event) {

		float deltaX = event.getX() - lastX;
		float deltaY = event.getY() - lastY;

		// move is in X axis
		if (Math.abs(deltaX) > Math.abs(deltaY)) {
			// right move
			if (deltaX > 0.0 && Math.abs(deltaX) > moveThreshold) {
				game.rightMoveHandler();
				// left move
			} else if (Math.abs(deltaX) > moveThreshold) {
				game.leftMoveHandler();
			}
			// move is in Y axis
		} else {
			// down move
			if (deltaY > 0.0) {
				game.downMoveHandler();
			}
		}
	}
}
